package yl.hs.bmipfull.utils;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import yl.hs.bmipfull.annotations.Excel;
import yl.hs.bmipfull.viewmodels.system.ExcelMap;

import java.io.*;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

/*
 * ExcelMapUtil
 * @category
 * @author 谢景广
 * @date 2022-09-20
 */
public class ExcelMapUtil {
    private final Logger log = LoggerFactory.getLogger(ExcelUtil.class);
    private String tmpName;

    public ExcelMapUtil(String tmpName){
        this.tmpName = tmpName;
    }

    public byte[] exportByTemplate(String tmpFilePath, int startRow, List<Map<String,Object>> data, List<ExcelMap> maps) throws IOException, InvalidFormatException {
        if(Tl.isEmpty(tmpFilePath)){
            throw new FileNotFoundException("未配置导出模板文件");
        }
        File file = new File(tmpFilePath);
        if(file.exists()) {
            InputStream inp = new FileInputStream(tmpFilePath);
            Workbook wb = WorkbookFactory.create(inp);
            Sheet sheet = wb.getSheetAt(0);
            var row = sheet.getRow(startRow);
            loadData(sheet,startRow, data, maps);
            var fileTmp = File.createTempFile(tmpName,".xlsx");
            var out = new FileOutputStream(fileTmp);
            wb.write(out);
            out.close();
            var byteData = ExcelUtil.fileToBinArray(fileTmp);
            fileTmp.delete();
            return byteData;
        }
        else
            throw new FileNotFoundException("导出模板文件不存在");
    }
    private void fillCell(Cell cell, String field, Map<String,Object> vo){
        try {
            var value = vo.get(field);
            String dateFormat = "yyyy-MM-dd";
            if (value instanceof Date)
            {
                cell.setCellValue(parseDateToStr(dateFormat, (Date) value));
            }
            else if (value instanceof BigDecimal)
            {
                cell.setCellValue(((BigDecimal) value).doubleValue());
            }
            else {
                cell.setCellValue((String) value);
            }
        }
        catch (Exception ee){
            log.error("导出数据异常字段"+field,ee);
        }
    }
    private String parseDateToStr(String pattern,Date d){
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        return format.format(d);
    }
    private Cell addCell(Row row, ExcelMap map, Map<String,Object> vo){
        Cell cell = row.createCell(map.getColumn());
        if(!Tl.isEmpty(map.getFieldCode())){
            var fs = vo.keySet().stream().filter(f->map.getFieldCode().contains(f)).toList();
            if(fs.size()>1){
                StringBuilder sb = new StringBuilder();
                for (var f:fs){
                    try {
                        sb.append(vo.get(f).toString());
                    }
                    catch (Exception ee){}
                }
                cell.setCellValue(sb.toString());
            }
            else if(fs.size()==1)
            {
                fillCell(cell,fs.get(0),vo);
            }
        }
        else{
            if(map.getDefValue() instanceof Double) {
                cell.setCellValue((Double)map.getDefValue());
            }
            else if(map.getDefValue() instanceof Boolean){
                cell.setCellValue((Boolean)map.getDefValue());
            }
            else{
                cell.setCellValue((String) map.getDefValue());
            }
        }
        return  cell;
    }
    private void loadData(Sheet sheet,int startRow, List<Map<String,Object>> data, List<ExcelMap> maps){
        for(var d : data) {
            Row row = sheet.createRow(startRow);
            for (var m:maps){
                addCell(row,m,d);
            }
            startRow++;
        }
    }
}
